package saei.bean;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Index;

import saei.bean.parametros.Sector;
import saei.bean.vo.UsuarioVO;

@SuppressWarnings("serial")
@Entity
@Table(name="Usuario")
public class Usuario  extends EntidadPersistente
{
    @Column(name="nombre")
    private String nombre;
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
	@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @ForeignKey(name="fk_usuario_representacion")
    @JoinColumn(name="id_representacion")
    private Representacion representacion;
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
	@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @ForeignKey(name="fk_usuario_sector")
    @JoinColumn(name="id_sector")
    private Sector sector;
    @Column(name="login", unique=true)
    @Index(name="uk_usuario")
    private String login;
    @Column(name="password")
    private String hashedPassword;
    @Column(name="fec_caducidad")
    @Temporal(value= TemporalType.TIMESTAMP)
    private Date fechaCaducida;
    @Column(name="esGerente")
    private boolean esGerente;
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
	@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    @JoinTable(name="Rol_Asignado", 
            joinColumns={@JoinColumn(name="id_usuario")},
            inverseJoinColumns={@JoinColumn(name="id_rol")})
    @ForeignKey(name="fk_roles_usuario", inverseName="fk_roles_usuario_rol")
    private Set<Rol> rolesAsignados;

    public Usuario(){}

    public Usuario (String login){
        this.login = login;
    }

    public Usuario (String nombre, Representacion representacion, Sector sector, 
                    String login, Date fechaCaducida, boolean esGerente){
		this.nombre = nombre;
		this.representacion = representacion;
		this.sector = sector;
		this.login = login;
		this.fechaCaducida = fechaCaducida;
		this.esGerente = esGerente;
		this.rolesAsignados = new HashSet<Rol>();

    }

    public String getNombre() {
    	return nombre;
    }

    public void setNombre(String nombre) {
		this.nombre = nombre;
    }

    public Representacion getRepresentacion() {
		return representacion;
    }

    public void setRepresentacion(Representacion representacion) {
		this.representacion = representacion;
    }

    public Sector getSector() {
		return sector;
    }

    public void setSector(Sector sector) {
		this.sector = sector;
    }

    public String getLogin() {
		return login;
    }

    public void setLogin(String login) {
		this.login = login;
    }

    public Date getFechaCaducida() {
		return fechaCaducida;
    }

    public void setFechaCaducida(Date fechaCaducida) {
		this.fechaCaducida = fechaCaducida;
    }

    public boolean esGerente() {
		return esGerente;
    }

    public void setEsGerente(boolean esGerente) {
		this.esGerente = esGerente;
    }

    public void agregarRol(Rol rol){
		if (!rolesAsignados.contains(rol))
			rolesAsignados.add(rol);
    }

    public void quitarRol(Rol rol){
		if (rolesAsignados.contains(rol))
			rolesAsignados.remove(rol);
    }
    
    public boolean puedeLeer() {
		for (Rol rol : rolesAsignados) 
		{
			if (rol.puedeLeer())
				return true;
		}
		
		return false;
    }

    public boolean puedeCrear() {
		for (Rol rol : rolesAsignados) 
		{
			if (rol.puedeCrear())
				return true;
		}
		
		return false;
    }

    public boolean puedeModificar() {
		for (Rol rol : rolesAsignados) {
			if (rol.puedeModificar())
				return true;
		}
		
		return false;
    }

    public boolean puedeEliminar() {
		for (Rol rol : rolesAsignados) {
			if (rol.puedeEliminar())
				return true;
			}
		
		return false;
    }

    public boolean puedeGenerarReportes() {
		for (Rol rol : rolesAsignados) {
			if (rol.puedeGenerarReportes())
				return true;
		}
		
		return false;
    }
	
    public UsuarioVO getVO() {
		UsuarioVO retVal = new UsuarioVO();
		
		retVal.setLogin(login);
		retVal.setNombre(nombre);
		retVal.setRepresentacion(representacion != null ? representacion.getNombre() : "");
		retVal.setSector(sector != null ? sector.getDescripcion() : "");
		
		retVal.setEsGerente(esGerente);
		retVal.setPuedeCrear(this.puedeCrear());
		retVal.setPuedeEliminar(this.puedeEliminar());
		retVal.setPuedeGenerarReportes(this.puedeGenerarReportes());
		retVal.setPuedeLeer(this.puedeLeer());
		retVal.setPuedeModificar(this.puedeModificar());
		
		return retVal;
	}

	public String getHashedPassword() {
		return hashedPassword;
	}

	public void setHashedPassword(String hashedPassword) {
		this.hashedPassword = hashedPassword;
	}
}
